﻿using System;
using System.Collections.Generic;

namespace School.Business
{
    using EDP.Common.Help;
    using EDP.Common;
    using EDP.Common.Model;
    using EDP.Database;

    using EDP.Framework;
    using EDP.Log;

    using EDP.Code;

    using School.Model;
    using School.Model.Organization;

    /// <summary>
    /// 学生业务操作
    /// </summary>
    public class StudentBLL : BusinessLogicBase<StudentBLL>
    {
        private readonly string m_LogPath = "学生管理";
        private readonly CodeBLL bll_Code = CodeBLL.Create();

        /// <summary>
        /// 保存学生信息
        /// </summary>
        /// <param name="keyValue"></param>
        /// <param name="item"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        [AutoLog(ActionEnum.Save, "学生信息")]
        public ResultModel<bool> SaveStudent(string keyValue, StudentModel item, IDBInstance db = null) {
            ResultModel<bool> ret = new ResultModel<bool>();
            ret.KeyValue = keyValue;
            bool isNewTranscation = false;

            var verify = item.Verify(keyValue);
            if (!verify.Content) {
                ret.ErrorLevel = verify.ErrorLevel;
                ret.ErrorCode = verify.ErrorCode;
                ret.Message = verify.Message;
                return ret;
            }

            try {
                if (db == null) {
                    db = DBFactory.Create();
                    isNewTranscation = true;
                    db.BeginTransaction();
                }

                ResultModel<int> result = new ResultModel<int>();

                if (!string.IsNullOrWhiteSpace(keyValue)) {
                    var old = this.GetStudent(keyValue, db).Content;
                    if (old == null || !old.HasValue()) {
                        ret.ErrorLevel = (int)ErrorLevelEnum.Warning;
                        ret.ErrorCode = (int)ErrorCodeEnum.EntityIsNull;
                        ret.Message = "修改的学生信息不存在";

                        if (isNewTranscation)
                            db.Rollback();
                        return ret;
                    }

                    item.Modify(keyValue, db);
                    item.Number = null; //编号不能修改
                }
                else {
                    item.Create(db);
                    var code = this.bll_Code.CreateCode("StudentNumber", db, item.ClassId);
                    item.Number = code != null && code.Content ? code.ContentExtend1 : string.Empty;

                    if (!item.Number.HasValue()) {
                        ret.ErrorLevel = (int)ErrorLevelEnum.GeneralError;
                        ret.ErrorCode = (int)ErrorCodeEnum.PropertyIsNull;
                        ret.Message = "学生编号为空";

                        if (isNewTranscation)
                            db.Rollback();
                        return ret;
                    }
                }

                //班级校验
                var dept = this.GetOrganization(item.ClassId, db).Content;
                if (dept == null || !dept.HasValue()) {
                    ret.ErrorLevel = (int)ErrorLevelEnum.Warning;
                    ret.ErrorCode = (int)ErrorCodeEnum.EntityIsNull;
                    ret.Message = "班级数据异常";

                    if (isNewTranscation)
                        db.Rollback();
                    return ret;
                }
                if (dept.TypeNumbers != "004") {
                    ret.ErrorLevel = (int)ErrorLevelEnum.Warning;
                    ret.ErrorCode = (int)ErrorCodeEnum.PropertyIsError;
                    ret.Message = "请选择班级";

                    if (isNewTranscation)
                        db.Rollback();
                    return ret;
                }
                item.CampusId = dept.OrganizationId;

                //保存数据
                if (keyValue.HasValue())
                    result = item.UpdateModel(db);
                else {
                    item.ValidateSQL = string.Format("where not exists (select 1 from t_school_student where Number = '{0}')", item.Number); //通过验证sql确保不会有重复的编号
                    result = item.InsertModel(db);
                    if (result.Content == 1)
                        this.bll_Code.UseCode("StudentNumber", db);
                }

                if (isNewTranscation)
                    db.Commit();
                ret.KeyValue = item.ID;

                if (result.Content == 1)
                    ret.Content = true;
                else if (result.Content == 0) {
                    ret.ErrorLevel = (int)ErrorLevelEnum.GeneralError;
                    ret.ErrorCode = (int)ErrorCodeEnum.OperateFail;
                    ret.Message = "保存学生信息失败";
                }
                else {
                    ret.ErrorLevel = result.ErrorLevel;
                    ret.ErrorCode = result.ErrorCode;
                    ret.Message = result.Message;
                }
            }
            catch (Exception e) {
                if (isNewTranscation)
                    db.Rollback();

                ret.ErrorLevel = (int)ErrorLevelEnum.SystemError;
                ret.ErrorCode = (int)ErrorCodeEnum.SystemError;
                ret.Message = "保存学生信息异常";

                LogHelp.WriteError(this.m_LogPath, ret.Message, e.Message, e.StackTrace);
                throw new Exception(e.Message, e);
            }

            return ret;
        }

        /// <summary>
        /// 新增学生信息
        /// </summary>
        /// <param name="item"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        [AutoLog(ActionEnum.Insert, "学生信息")]
        public ResultModel<bool> AddStudent(StudentModel item, IDBInstance db = null) {
            return this.SaveStudent(string.Empty, item, db);
        }

        /// <summary>
        /// 修改学生信息
        /// </summary>
        /// <param name="item"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        [AutoLog(ActionEnum.Update, "学生信息")]
        public ResultModel<bool> UpdateStudent(StudentModel item, IDBInstance db = null) {
            return this.SaveStudent(item.ID, item, db);
        }

        /// <summary>
        /// 删除学生信息
        /// </summary>
        /// <param name="keyValue"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        [AutoLog(ActionEnum.Delete, "学生信息")]
        public ResultModel<bool> DeleteStudent(string keyValue, IDBInstance db = null) {
            ResultModel<bool> ret = new ResultModel<bool>();

            if (!keyValue.HasValue()) {
                ret.ErrorLevel = (int)ErrorLevelEnum.Warning;
                ret.ErrorCode = (int)ErrorCodeEnum.KeyValueIsNull;
                ret.Message = EnumHelp.GetEnumDescription(ErrorCodeEnum.KeyValueIsNull);
                return ret;
            }

            ret.KeyValue = keyValue;
            bool isNewTranscation = false;

            try {
                if (db == null) {
                    db = DBFactory.Create();
                    isNewTranscation = true;
                    db.BeginTransaction();
                }

                var item = this.GetStudent(keyValue, db).Content;
                if (item == null || !item.HasValue()) {
                    ret.ErrorLevel = (int)ErrorLevelEnum.Warning;
                    ret.ErrorCode = (int)ErrorCodeEnum.EntityIsNull;
                    ret.Message = "删除的学生信息不存在";

                    if (isNewTranscation)
                        db.Rollback();
                    return ret;
                }

                var result = item.DeleteModel(db);

                if (isNewTranscation)
                    db.Commit();

                if (result.Content == 1)
                    ret.Content = true;
                else if (result.Content == 0) {
                    ret.ErrorLevel = (int)ErrorLevelEnum.GeneralError;
                    ret.ErrorCode = (int)ErrorCodeEnum.OperateFail;
                    ret.Message = "删除学生信息失败";
                }
                else {
                    ret.ErrorLevel = result.ErrorLevel;
                    ret.ErrorCode = result.ErrorCode;
                    ret.Message = result.Message;
                }
            }
            catch (Exception e) {
                if (isNewTranscation)
                    db.Rollback();

                ret.ErrorLevel = (int)ErrorLevelEnum.SystemError;
                ret.ErrorCode = (int)ErrorCodeEnum.SystemError;
                ret.Message = "删除学生信息异常";

                LogHelp.WriteError(this.m_LogPath, ret.Message, e.Message, e.StackTrace);
                throw new Exception(e.Message, e);
            }

            return ret;
        }

        /// <summary>
        /// 获取学生信息
        /// </summary>
        /// <param name="keyValue"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public ResultModel<StudentModel> GetStudent(string keyValue, IDBInstance db = null) {
            ResultModel<StudentModel> ret = new ResultModel<StudentModel>();
            if (keyValue.IsEmpty()) {
                ret.ErrorLevel = (int)ErrorLevelEnum.GeneralError;
                ret.ErrorCode = (int)ErrorCodeEnum.EntityIsNull;
                ret.Message = "主键值为空";
                return ret;
            }
            ret.Content = new StudentModel();
            ret.KeyValue = keyValue;

            bool isNewTranscation = false;

            try {
                if (db == null) {
                    db = DBFactory.Create();
                    isNewTranscation = true;
                    db.BeginTransaction();
                }

                ret.Content.ID = keyValue;
                ret.Content.Query(db);

                if (ret.Content != null && ret.Content.HasValue()) {
                    ret.Content.School.ID = ret.Content.ClassId;
                    ret.Content.School.Query(db);
                    string sql = ret.Content.School.OrganizationPathList.GetDefaultQuerySQL() + string.Format(" where '{0}' like FullCode + '%' order by FullCode", ret.Content.School.FullCode);
                    ret.Content.School.OrganizationPathList.Query(sql, db);
                }

                if (isNewTranscation)
                    db.Commit();

                ret.KeyValue = ret.Content.ID;
            }
            catch (Exception e) {
                if (isNewTranscation)
                    db.Rollback();

                ret.ErrorLevel = (int)ErrorLevelEnum.SystemError;
                ret.ErrorCode = (int)ErrorCodeEnum.SystemError;
                ret.Message = "获取学生信息异常";

                LogHelp.WriteError(this.m_LogPath, ret.Message, e.Message, e.StackTrace);
                throw new Exception(e.Message, e);
            }

            return ret;
        }

        /// <summary>
        /// 获取学生信息列表
        /// </summary>
        /// <param name="queryModel"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public ResultModel<List<StudentModel>> GetStudentList(StudentQueryModel queryModel, IDBInstance db = null) {
            ResultModel<List<StudentModel>> ret = new ResultModel<List<StudentModel>>();
            ret.Content = new List<StudentModel>();
            bool isNewTranscation = false;

            try {
                if (db == null) {
                    db = DBFactory.Create();
                    isNewTranscation = true;
                    db.BeginTransaction();
                }

                if (queryModel.Page != null) {
                    if (queryModel.Page.SortName.IsEmpty()) {
                        queryModel.Page.SortName = "Number";
                        queryModel.Page.SortDirection = SortDirection.ASC.ToString();
                    }

                    ret.Content.Query(queryModel.Page, queryModel, db);
                    ret.Page = queryModel.Page;
                }
                else {
                    ret.Content.Query(queryModel, db);
                    ret.Content.Sort(SortDirection.ASC, "Number");
                }

                if (ret.Content != null && ret.Content.HasValue()) {
                    foreach (var item in ret.Content) {
                        item.School.ID = item.ClassId;
                        item.School.Query(db);
                    }
                }

                if (isNewTranscation)
                    db.Commit();
            }
            catch (Exception e) {
                if (isNewTranscation)
                    db.Rollback();

                ret.ErrorLevel = (int)ErrorLevelEnum.SystemError;
                ret.ErrorCode = (int)ErrorCodeEnum.SystemError;
                ret.Message = "获取学生信息列表异常";

                LogHelp.WriteError(this.m_LogPath, ret.Message, e.Message, e.StackTrace);
                throw new Exception(e.Message, e);
            }

            return ret;
        }

        /// <summary>
        /// 获取组织列表
        /// </summary>
        /// <param name="db"></param>
        /// <returns></returns>
        public ResultModel<List<OrganizationModel>> GetOrganizationList(IDBInstance db = null) {
            ResultModel<List<OrganizationModel>> ret = new ResultModel<List<OrganizationModel>>();
            ret.Content = new List<OrganizationModel>();
            bool isNewTranscation = false;

            try {
                if (db == null) {
                    db = DBFactory.Create();
                    isNewTranscation = true;
                    db.BeginTransaction();
                }

                ret.Content.Query(db);
                if (ret.Content != null && ret.Content.Count > 0)
                    ret.Content.Sort(SortDirection.ASC, "FullCode");

                if (isNewTranscation)
                    db.Commit();
            }
            catch (Exception e) {
                if (isNewTranscation)
                    db.Rollback();

                ret.ErrorLevel = (int)ErrorLevelEnum.SystemError;
                ret.ErrorCode = (int)ErrorCodeEnum.SystemError;
                ret.Message = "获取组织列表异常";

                LogHelp.WriteError(this.m_LogPath, ret.Message, e.Message, e.StackTrace);
                throw new Exception(e.Message, e);
            }

            return ret;
        }

        /// <summary>
        /// 获取组织
        /// </summary>
        /// <param name="keyValue"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public ResultModel<OrganizationModel> GetOrganization(string keyValue, IDBInstance db = null) {
            ResultModel<OrganizationModel> ret = new ResultModel<OrganizationModel>();
            ret.Content = new OrganizationModel();
            bool isNewTranscation = false;

            try {
                if (db == null) {
                    db = DBFactory.Create();
                    isNewTranscation = true;
                    db.BeginTransaction();
                }

                ret.Content.ID = keyValue;
                ret.Content.Query(db);

                if (isNewTranscation)
                    db.Commit();
            }
            catch (Exception e) {
                if (isNewTranscation)
                    db.Rollback();

                ret.ErrorLevel = (int)ErrorLevelEnum.SystemError;
                ret.ErrorCode = (int)ErrorCodeEnum.SystemError;
                ret.Message = "获取组织异常";

                LogHelp.WriteError(this.m_LogPath, ret.Message, e.Message, e.StackTrace);
                throw new Exception(e.Message, e);
            }

            return ret;
        }
    }
}
